#include "Func.h"

#include <string.h>
#include <fan-llvm/core/Core.h>
#include "Type.h"
#include "UnsupportedErr.h"


Type* Func_classType = NULL;
VTable* Func_classVTable = NULL;


/**********************************************
 *
 * Methods and fields
 *
 **********************************************/


/* Type returns() */
Type* Func_returns(Func* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.returns not implemented yet"));
}


/* Int arity() */
Int Func_arity(Func* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.arity not implemented yet"));
}


/* Param[] params() */
List* Func_params(Func* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.params not implemented yet"));
}


/* Method? method() */
Method* Func_method(Func* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.method not implemented yet"));
}


/* R callList(Obj?[]? args) */
Val Func_callList(Func* self, List* args)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.callList not implemented yet"));
}


/* R callOn(Obj? target, Obj?[]? args) */
Val Func_callOn(Func* self, NullableObj target, List* args)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.callOn not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call_0(Func* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call_1(Func* self, Val a)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call_2(Func* self, Val a, Val b)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call_3(Func* self, Val a, Val b, Val c)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call_4(Func* self, Val a, Val b, Val c, Val d)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call_5(Func* self, Val a, Val b, Val c, Val d, Val e)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call_6(Func* self, Val a, Val b, Val c, Val d, Val e, Val f)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call_7(Func* self, Val a, Val b, Val c, Val d, Val e, Val f, Val g)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* R call(A a, B b, C c, D d, E e, F f, G g, H h) */
Val Func_call(Func* self, Val a, Val b, Val c, Val d, Val e, Val f, Val g, Val h)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.call not implemented yet"));
}


/* Func bind(Obj?[] args) */
Func* Func_bind(Func* self, List* args)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.bind not implemented yet"));
}


/* Func retype(Type t) */
Func* Func_retype(Func* self, Type* t)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Func.retype not implemented yet"));
}


/**********************************************
 *
 * Type-system functions
 *
 **********************************************/


Type* Func_initType(void)
{
  if (Func_classType == NULL)
  {
    Type* baseType = Obj_initType();
    VTable* vtable = Func_initVTable();
    Type* type = Type_new("Func", baseType, vtable, sizeof(Func), sizeof(FuncVTable));
    Type_registerMethodImplementation(type, "arity", Func_arity, 0);
    Type_registerMethodImplementation(type, "bind", Func_bind, 1);
    Type_registerMethodImplementation(type, "call", Func_call_0, 0);
    Type_registerMethodImplementation(type, "call", Func_call_1, 1);
    Type_registerMethodImplementation(type, "call", Func_call_2, 2);
    Type_registerMethodImplementation(type, "call", Func_call_3, 3);
    Type_registerMethodImplementation(type, "call", Func_call_4, 4);
    Type_registerMethodImplementation(type, "call", Func_call_5, 5);
    Type_registerMethodImplementation(type, "call", Func_call_6, 6);
    Type_registerMethodImplementation(type, "call", Func_call_7, 7);
    Type_registerMethodImplementation(type, "call", Func_call, 8);
    Type_registerMethodImplementation(type, "callList", Func_callList, 1);
    Type_registerMethodImplementation(type, "callOn", Func_callOn, 2);
    Type_registerMethodImplementation(type, "method", Func_method, 0);
    Type_registerMethodImplementation(type, "params", Func_params, 0);
    Type_registerMethodImplementation(type, "returns", Func_returns, 0);
    Type_registerMethodImplementation(type, "retype", Func_retype, 1);
    Func_classType = type;
    Func_initStatic();
  }
  return Func_classType;
}


VTable* Func_initVTable(void)
{
  if (Func_classVTable == NULL)
  {
    VTable* vtable = memoryAlloc(sizeof(FuncVTable));
    memcpy(vtable, Obj_initVTable(), sizeof(FanObjVTable));
    ((FuncVTable*)vtable)->call_0 = Func_call_0;
    ((FuncVTable*)vtable)->call_1 = Func_call_1;
    ((FuncVTable*)vtable)->call_2 = Func_call_2;
    ((FuncVTable*)vtable)->call_3 = Func_call_3;
    ((FuncVTable*)vtable)->call_4 = Func_call_4;
    ((FuncVTable*)vtable)->call_5 = Func_call_5;
    ((FuncVTable*)vtable)->call_6 = Func_call_6;
    ((FuncVTable*)vtable)->call_7 = Func_call_7;
    ((FuncVTable*)vtable)->call = Func_call;
    ((FuncVTable*)vtable)->callList = Func_callList;
    ((FuncVTable*)vtable)->callOn = Func_callOn;
    Func_classVTable = vtable;
  }
  return Func_classVTable;
}


void Func_initStatic(void)
{
}
